//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2007
//
// Property pages.
//

# include "StdAfx.h"
# include "PropertyPages.h"
# include "Globals.h"

CPropertyPages::~CPropertyPages () {
	for (unsigned int nPage = 0; nPage < m_vecPages.size (); ++ nPage)
		delete m_vecPages [nPage];
}

void CPropertyPages::AddPage (CPropertyPages::CPage * _pPage) {
	_pPage->m_pPP = this;
	m_vecPages.push_back (_pPage);
}

void CPropertyPages::ShowModal (HWND _hWndParent, WORD _wResCaptionID, int _nStartPage) {
	const size_t cPages = m_vecPages.size ();
	PROPSHEETPAGE * const pPages = new PROPSHEETPAGE [cPages];
	::memset (pPages, 0, sizeof (PROPSHEETPAGE)*cPages);

	for (size_t cPage = 0; cPage < cPages; ++ cPage) {
		pPages [cPage].dwSize      = sizeof (PROPSHEETPAGE);
		pPages [cPage].dwFlags     = PSP_DEFAULT;

		const WORD wResID = m_vecPages [cPage]->m_wResID;
		pPages [cPage].pszTemplate = MAKEINTRESOURCE (wResID);
		pPages [cPage].pfnDlgProc  = CPropertyPages::CPage::_DlgProc;
		pPages [cPage].hInstance   = g_hResInst;
		pPages [cPage].lParam      = reinterpret_cast<LPARAM> (m_vecPages [cPage]);
	}

	PROPSHEETHEADER psh;
	::memset (& psh, 0, sizeof (psh));
	psh.dwSize      = sizeof (psh);
	psh.dwFlags     = PSH_PROPSHEETPAGE | PSH_USECALLBACK;
	psh.hwndParent  = _hWndParent;
	psh.hInstance   = g_hResInst;
//	psh.pfnCallback = _TabSheetProc;
	psh.nPages      = cPages;
	psh.nStartPage  = _nStartPage;
	if (psh.nStartPage > cPages)
		psh.nStartPage = 0;
	psh.ppsp        = pPages;
	psh.pszCaption = reinterpret_cast<LPCTSTR> (_wResCaptionID);

	// Show the wizard.
	::PropertySheet (& psh);

	delete [] pPages;

}

//////////////////////////////////////////////////////////////////////

# ifndef PSM_INDEXTOHWND
#	define PSM_INDEXTOHWND            (WM_USER + 130)
# endif

HWND CPropertyPages::CPage::GetPage (size_t _cPageIdx) {
	return (HWND) ::SendMessage (::GetParent (m_hWnd), PSM_INDEXTOHWND, _cPageIdx, 0);
}

INT_PTR CALLBACK CPropertyPages::CPage::_DlgProc (HWND _hWnd, UINT _uMsg, WPARAM _wParam, LPARAM _lParam) {
	switch (_uMsg) {
		case WM_INITDIALOG: {
			PROPSHEETPAGE * const pPage = reinterpret_cast<PROPSHEETPAGE *> (_lParam);
			CPropertyPages::CPage * const pThis = reinterpret_cast<CPropertyPages::CPage *> (pPage->lParam);
			::SetWindowLong (_hWnd, GWL_USERDATA, pPage->lParam);
			pThis->m_hWnd = _hWnd;

			CenterPropertyPages (_hWnd);

			const HWND hwndFocus = (HWND) _wParam;
			const BOOL bRet = pThis->OnInit (hwndFocus) ? TRUE : FALSE;

			return bRet;
		}

		default: {
			CPropertyPages::CPage * const pThis = reinterpret_cast<CPropertyPages::CPage *> (::GetWindowLong (_hWnd, GWL_USERDATA));
			if (pThis == NULL)
				// NOTE: some messages come before WM_INITDIALOG, so thay could not be dispatched using any virtual function.
				return 0;

			pThis->m_hWnd = _hWnd;
			return pThis->OnMessage (_uMsg, _wParam, _lParam);
		}
	}
}

bool CPropertyPages::CPage::OnNotify (int _idCtrl, NMHDR * _pInfo) {
	switch (_pInfo->code) {
		case PSN_SETACTIVE: {
			const PSHNOTIFY * const pPSHNotify = reinterpret_cast<const PSHNOTIFY *> (_pInfo);
			OnActivatePage (pPSHNotify);
			break;
		}

		case PSN_APPLY: {
			const PSHNOTIFY * const pPSHNotify = reinterpret_cast<const PSHNOTIFY *> (_pInfo);
			OnApply (pPSHNotify);
			break;
		}
	}

	return false;
}

/////////////////////////////////////////////////////////////////

void CenterPropertyPages (HWND _hPage) {
	const HWND hMain = ::GetParent (_hPage);

	if (::GetProp (hMain, "Centered") != NULL)
		return;

	RECT rectParent;
	::GetWindowRect (::GetParent (hMain), & rectParent);

	RECT rect;
	::GetWindowRect (hMain, & rect);

	::SetWindowPos (
		hMain, NULL,
		(rectParent.right + rectParent.left)/2 - (rect.right - rect.left)/2,
		(rectParent.top + rectParent.bottom)/2 - (rect.bottom - rect.top)/2,
		0, 0,
		SWP_ASYNCWINDOWPOS | SWP_NOZORDER | SWP_NOSIZE
	);

	::SetProp (hMain, "Centered", (HANDLE) 1);
}
